package com.le.tester.imooc.oldfairy.coding.annotation;


import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.LinkedList;

/**
 * createTime：2023/5/19 10:22
 * description：ObjectFactory
 */
public class ObjectFactory {


    public static <T> T newInstance(Class<T> cls) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //获取注解
        Annotation[] annotations = cls.getAnnotations();
        //切片接口数组
        LinkedList<IAspect> iAspects = new LinkedList<>();

        //遍历注解
        for (Annotation anItem : annotations) {
            if (anItem instanceof Aspect) {
                Class type = ((Aspect) anItem).type();
                IAspect iAspect = (IAspect) (type.getConstructor().newInstance());
                iAspects.push(iAspect);
            }
        }

        T instance = cls.getConstructor().newInstance();

        return (T) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), (proxy, method, args) -> {
            iAspects.forEach(aspect -> aspect.before());
            Object result = method.invoke(instance);
            iAspects.forEach(aspect -> aspect.after());
            return result;
        });

    }

    @Test
    public void test() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, InterruptedException {
        //测试用例中使用的是Order，那么ObjectFactory将会扫描Order中的注解
        IOrder order = ObjectFactory.newInstance(Order.class);
        //order.pay();
        order.show();
    }
}
